package repository

import (
	"gorm.io/gorm"

	"svcSrv/domain/model"
)

// 创建需要实现的接口
type ISvcRepository interface {
	// 初始化表
	InitTable() error
	// 根据 ID 查处找数据
	FindSvcByID(int64) (*model.Svc, error)
	// 创建一条 Svc 数据
	CreateSvc(*model.Svc) (int64, error)
	// 根据 ID 删除一条 Svc 数据
	DeleteSvcByID(int64) error
	// 修改一条数据
	UpdateSvc(*model.Svc) error
	// 查找 Svc 所有数据
	FindSvcList(page *model.Page) (int64, []model.Svc, error)
}

type SvcRepository struct {
	mysqlDb *gorm.DB
}

// 创建 SvcRepository
func NewSvcRepository(db *gorm.DB) ISvcRepository {
	return &SvcRepository{mysqlDb: db}
}

// 初始化表
func (p *SvcRepository) InitTable() error {
	return p.mysqlDb.AutoMigrate(&model.Svc{}, &model.SvcPort{})
}

// 根据 ID 查找 Svc 信息
func (p *SvcRepository) FindSvcByID(svcID int64) (svc *model.Svc, err error) {
	svc = &model.Svc{}
	return svc, p.mysqlDb.Preload("SvcPort").First(svc, svcID).Error
}

// 创建 Svc 信息
func (p *SvcRepository) CreateSvc(svc *model.Svc) (int64, error) {
	return svc.ID, p.mysqlDb.Create(svc).Error
}

// 根据 ID 删除 Svc 信息
func (p *SvcRepository) DeleteSvcByID(svcID int64) error {
	tx := p.mysqlDb.Begin()
	//遇到问题回滚
	defer func() {
		if err := recover(); err != nil {
			tx.Rollback()
		}
	}()
	if tx.Error != nil {
		return tx.Error
	}

	//删除 Svc 信息
	if err := tx.Where("id = ?", svcID).Delete(&model.Svc{BaseModel: model.BaseModel{ID: svcID}}).Error; err != nil {
		tx.Rollback()
		return err
	}
	//删除 svcport 信息
	if err := tx.Where("svc_id = ?", svcID).Delete(&model.SvcPort{SvcID: svcID}).Error; err != nil {
		tx.Rollback()
		return err
	}
	return tx.Commit().Error
}

// 更新 Svc 信息
func (p *SvcRepository) UpdateSvc(svc *model.Svc) error {
	tx := p.mysqlDb.Begin()
	//遇到问题回滚
	defer func() {
		if err := recover(); err != nil {
			tx.Rollback()
		}
	}()
	if tx.Error != nil {
		return tx.Error
	}

	if err := tx.Model(&svc).Updates(svc).Error; err != nil {
		tx.Rollback()
		return err
	}
	for _, port := range svc.SvcPort {
		if err := tx.Model(&port).Save(port).Error; err != nil {
			tx.Rollback()
			return err
		}
	}
	return tx.Commit().Error
}

// 获取结果集
func (p *SvcRepository) FindSvcList(page *model.Page) (total int64, svcList []model.Svc, err error) {
	if result := p.mysqlDb.Model(&model.Svc{}).Count(&total); result.Error != nil {
		return total, svcList, err
	}
	return total, svcList, p.mysqlDb.Model(&model.Svc{}).Preload("SvcPort").Scopes(Paginate(page)).Find(&svcList).Error
}
